#ifndef __CALC_MEM_H
#define __CALC_MEM_H

#pragma pack(push,1)

//mem struct
//Buf[static mem]SEP[cache mem]SP[empty mem]EP[Grain mem]

typedef struct _MS_GRAIN
{
	struct _MS_GRAIN *pNext;
}MS_GRAIN;

#ifndef _MEM_ITEM
#define _MEM_ITEM			\
int nMemSize;		\
unsigned char *pMemBuf;	\
unsigned char *pMemSEp;	\
unsigned char *pMemSp;	\
unsigned char *pMemEp;	\
struct _MS_GRAIN *pMemGE28
#endif

typedef struct _MS_DATA
{
	_MEM_ITEM;
}MS_DATA;

#pragma pack(pop)

#ifdef _DEBUG
#define OnMemOut()				OnMemOut_MS();
void OnMemOut_MS();
#else
#define OnMemOut()
#endif

/////////////////////////////////////////////
#ifndef MallocMemE
#define MallocMemE(p,size,type,lib,OnMemOutCode){\
	(p) = (type*)((lib)->pMemEp - (size));\
	if ((unsigned char*)(p) >= (lib)->pMemSp)\
		(lib)->pMemEp = (unsigned char*)(p);\
	else{\
		OnMemOut();\
		OnMemOutCode;\
	}\
}
#endif

#ifndef MallocMemGE28
#define MallocMemGE28(p,type,lib,OnMemOutCode){\
	if (lib->pMemGE28){\
		(p) = (type*)(lib->pMemGE28);\
		lib->pMemGE28 = ((MS_GRAIN*)(p))->pNext; \
	}\
	else{\
		p = (type*)(lib->pMemEp - 28);\
		if ((unsigned char*)(p) >= lib->pMemSp)\
			lib->pMemEp = (unsigned char*)(p);\
		else{\
			OnMemOut();\
			OnMemOutCode;\
		}\
	}\
}
#endif

#ifndef FreeMemGE28
#define FreeMemGE28(p, lib){\
	((MS_GRAIN*)(p))->pNext = lib->pMemGE28;\
	lib->pMemGE28 = (MS_GRAIN*)(p);\
}
#endif

#ifndef FreeMemE
#define FreeMemE(lib){\
	(lib)->pMemEp = (lib)->pMemBuf + (lib)->nMemSize;\
	(lib)->pMemGE28 = 0;\
}
#endif
//////////////////////////////////////////////
#ifndef MallocMemS
#define MallocMemS(p,size,type,lib,OnMemOutCode){	\
	p=(type*)((lib)->pMemSp);	\
	unsigned char *_pSp = ((unsigned char*)(p)) + (size);	\
	if (_pSp <= (lib)->pMemEp)	\
		(lib)->pMemSp = _pSp;	\
	else{\
		OnMemOut();\
		OnMemOutCode;\
	}\
}
#endif

#ifndef FreeMemS
#define FreeMemS(lib){	\
	(lib)->pMemSp = (lib)->pMemSEp;	\
}
#endif

#ifndef StoreMemSp
#define StoreMemSp(p,type,lib)	\
	p=(type*)((lib)->pMemSp)
#endif

#ifndef RestoreMemSp
#define RestoreMemSp(p,lib)	\
	((lib)->pMemSp)=(unsigned char*)(p)
#endif
/////////////////////////////////////////////////////
#ifndef MallocStaticMem
#define MallocStaticMem(p,size,type,lib,OnMemOutCode){\
	(p) = (type*)((lib)->pMemSEp);\
	unsigned char *_pSp = ((unsigned char*)(p)) + (size);	\
	if (_pSp <= (lib)->pMemEp){\
		(lib)->pMemSEp = _pSp;\
		FreeMemS(lib);\
	}\
	else{\
		OnMemOut();\
		OnMemOutCode;\
	}\
}
#endif

#ifndef StoreMemSEp
#define StoreMemSEp(p,type,lib)	\
	p=(type*)((lib)->pMemSEp)
#endif
/////////////////////////////////////////////////
#ifndef ResetCalcMem
#define ResetCalcMem(lib){\
	(lib)->pMemSEp = (lib)->pMemBuf;\
	FreeMemS(lib);\
	FreeMemE(lib);\
}
#endif
/////////////////////////////////////////////////
#ifndef InitCalcMemSys
#define InitCalcMemSys(pMem,nSize,pLib){\
	(pLib)->nMemSize = (nSize);	\
	(pLib)->pMemBuf = (unsigned char*)(pMem);	\
	ResetCalcMem(pLib);	\
}
#endif

int _FourByteAlign(unsigned int unSize);
#define FourByteAlign(unSize)			\
	_FourByteAlign((unsigned int)(unSize))

void _CopyCalcMem(unsigned char *pDest, unsigned char *pSrc, int nMemSize);
#define CopyCalcMem(pDest,pSrc,nMemSize)	\
	_CopyCalcMem((unsigned char*)(pDest),(unsigned char*)(pSrc),nMemSize)

int _GetCalcMemUse(MS_DATA *pLib);
#define GetCalcMemUse(pLib)		\
	_GetCalcMemUse((MS_DATA*)(pLib))


#endif